 
// A. TOMPSETT 8/2018: Code to estimate regression adjusted with centred covariates 

/*-----------------------------------------------------------------------------

 [BETA VERSION]

 This may contain errors. Please notify me of any errors you find.
 
 ------------------------------------------------------------------------------

 Syntax:
 
 reg_centred Yvar Xvarlist, control(control_vars) 

 Function regresses the outcome variable Yvar on the list of treated variables Xvarlist, controlling for the variables listed in control_vars.  Before including the variables in control_vars as controls, the function first centers or demeans the variables with respect to the same sample and weighting function used in the regression.  
 
 The function accepts all options that regress accepts.  
 
 Example commands:
 
 reg_centered dep indep1, control(z1 z2 z3) 
 
 reg_centered dep indep1 [iweight = iw], control(z1 z2 z3) nocons


 ------------------------------------------------------------------------------
 
 Requred arguments: 
 
 Yvar: dependent variable  
 Xvarlist: independnet variables 
 control: control variables
 ------------------------------------------------------------------------------
 
 Options:
 
 See STATA help file for regress.  
 
 ------------------------------------------------------------------------------

 References:

Lin, W. (2013). Agnostic notes on regression adjustments to experimental data: Reexamining Freedman’s critique. The Annals of Applied Statistics, 7(1), 295-318.
      
and 

Gibbons, C. E., Serrato, J. C. S., & Urbancic, M. B. (2018). Broken or fixed effects? Journal of Econometric Methods (forthcoming)

and

Imbens, G. W., & Rubin, D. B. (2015). Causal inference in statistics, social, and biomedical sciences. Cambridge University Press.
 
 -----------------------------------------------------------------------------*/

program reg_centered, eclass byable(recall) sortpreserve

syntax varlist [if] [in] [fweight aweight iweight], control(varlist) [*]

/*--------PARSING COMMANDS AND SETUP-------*/

//establish sample

capture drop touse
marksample touse				
gen touse = `touse'

//detect if nocons specified 

local nocons = 0

while ( regexm("`options'","nocons")==1 ) {
	local nocons = 1
	local options = regexr("`options'", "nocons", "")
}

//Extract outcome variables and treatment variables

//parsing variables
loc Y = word("`varlist'",1)		

loc listing "`varlist'"
loc X ""

//make sure that Y is not included in the other_var list

foreach i of loc listing {
	if "`i'" ~= "`Y'"{
		loc X "`X' `i'"		
	}
}

//center variables and create interaction terms

capture drop *czz

foreach controlvar in `control' {
	quietly: summarize `controlvar' if `touse' & `Y' != . [`weight'`exp'], meanonly
	quietly: gen double `controlvar'_czz = `controlvar' - r(mean)
	
	foreach treatvar in `X' {
		quietly: gen double tzz_`treatvar'_`controlvar'_czz = `treatvar' * `controlvar'_czz
	}
	
}

//run regression

if `nocons' == 0 {
	reg `Y' `X' *czz  [`weight'`exp'] if `touse' , `options' 
}

if `nocons' == 1 {
	reg `Y' `X' tzz*czz [`weight'`exp'] if `touse' , `options' nocons
}

capture drop *czz

end



